We are migrating the bug tracker to github Issues. This is now the preferred way to report NASM bugs.
Self-registration is disabled due to spam issue (mail gorcunov@gmail.com or hpa@zytor.com to create an account)
This is running with nasm-2.14.03rc2-448-gca2d991e from https://github.com/ecm-pushbx/nasm/commit/ca2d991ec9240cb35bad9cd467aea1eab197784d The following example results in a segmentation fault when assembling to ELF format with debugging information (-felf -g). Assembling without debugging information or to bin format instead does not exhibit this problem. If I drop the second lpar usage, or the lleave, the error also does not occur any longer. $ nasm --version NASM version 2.15rc0 compiled on Nov 22 2019 $ cat test.asm %include "lmacros2.mac" bits 32 lframe near lpar dword, EKey lpar dword, length lenter lleave $ hg -R ../lmacros/ id aa2ecb95d799 tip $ nasm -felf -g test.asm -o test.o -I ../lmacros/ Segmentation fault $ nasm -felf test.asm -o test.o -I ../lmacros/ $ nasm -fbin -g test.asm -o test.o -I ../lmacros/ $ nasm -fbin test.asm -o test.o -I ../lmacros/ $ This example uses lmacros2.mac and lmacros1.mac from https://hg.ulukai.org/ecm/lmacros/rev/aa2ecb95d799 and the expected output is: $ nasm -fbin -g test.asm -o test.o -I ../lmacros/ -l /dev/stderr 1 %include "lmacros2.mac" 1 <1> [list -] 14 <1> [list -] 2 3 bits 32 4 5 lframe near 6 lpar dword, EKey 7 lpar dword, length 8 00000000 5589E5 lenter 9 00000003 5D lleave 10 $ That is, "push ebp" \ "mov ebp, esp" \ "pop ebp" in the default section.
Here's the relevant part of the listing output with the -Ls switch, when assembling into bin format. $ nasm -fbin -g test.asm -o test.o -I ../lmacros/ -l /dev/stderr -Ls [...] 1 %include "lmacros2.mac" 1 <1> [list -] [...] 2 3 bits 32 4 5 lframe near 5 ;;; %define [LFRAME::11] %$bits 32 5 ;;; %define [LFRAME::11] %$base_size 4 5 ;;; %define [LFRAME::11] %$near_offset 4 5 ;;; %define [LFRAME::11] %$far_offset 8 5 ;;; %define [LFRAME::11] %$int_offset 12 5 ;;; %define [LFRAME::11] %$inner 0 5 ;;; %define [LFRAME::11] %$nested 0 5 ;;; %define [LFRAME::11] %$autoret 5 ;;; %define [LFRAME::11] %$autoret near 5 ;;; %define [LFRAME::11] %$parofs 4 5 ;;; %define [LFRAME::11] %$pars_size 0 5 ;;; %define [LFRAME::11] %$pars_return_size 0 5 ;;; %define [LFRAME::11] %$parlist 5 ;;; %define [LFRAME::11] %$labellist empty,empty,empty 5 ;;; %define [LFRAME::11] %$ofs 0 5 ;;; %define [LFRAME::11] %$enter 0 5 ;;; %define [LFRAME::11] %$req 0 5 ;;; %define [LFRAME::11] %$usereq 0 5 ;;; %define [LFRAME::11] %$emit 1 5 ;;; %define [LFRAME::11] %$restore_frame_ofs 0 5 ;;; %define [LFRAME::11] %$pars_inner_size 0 6 lpar dword, EKey 6 ;;; %define [LFRAME::11] %$varsize 4 6 ;;; %define [LFRAME::11] %$newlabel EKey 6 ;;; %define [LFRAME::11] %$labellist EKey,undefined,,empty,empty,empty 6 ;;; %define [LFRAME::11] %$pars_size 4 6 ;;; %define [LFRAME::11] %$parlist 4,EKey 6 ;;; %define [LFRAME::11] %$req 1 7 lpar dword, length 7 ;;; %define [LFRAME::11] %$varsize 4 7 ;;; %define [LFRAME::11] %$newlabel length 7 ;;; %define [LFRAME::11] %$labellist length,undefined,,EKey,undefined,,empty,empty,empty 7 ;;; %define [LFRAME::11] %$pars_size 8 7 ;;; %define [LFRAME::11] %$parlist 4,EKey,4,length 7 ;;; %define [LFRAME::11] %$req 1 8 00000000 5589E5 lenter 8 ;;; %define [LFRAME::11] %$wasearly 0 8 ;;; %define [LFRAME::11] %$early 0 8 ;;; %define [LENTER::11] %$lsizevariables 0 8 ;;; %define [LENTER::11] %$req 1 8 ;;; %define [LENTER::11] %$enter_emitted 0 8 ;;; %define [LENTER::11] %$enter 1 8 ;;; %define [LENTER::11] %$186 0 8 ;;; %define [LENTER::11] %$newlabel frame_ebp 8 ;;; %define [LENTER::11] %$labellist frame_ebp,undefined,,length,undefined,,EKey,undefined,,empty,empty,empty 8 ;;; %define ?frame_ebp 0 8 ;;; %define [LENTER::11] %$newlabel frame_eip 8 ;;; %define [LENTER::11] %$labellist frame_eip,undefined,,frame_ebp,undefined,,length,undefined,,EKey,undefined,,empty,empty,empty 8 ;;; %define ?frame_eip 4 8 ;;; %define [LENTER::11] %$lsizeparameters 8 8 ;;; %define [LENTER::11] %$pars_size 4 8 ;;; %define ?EKey 12 8 ;;; %define [LENTER::11] %$pars_size 0 8 ;;; %define ?length 8 9 00000003 5D lleave 9 ;;; %define [LENTER::11] %$186 0 9 ;;; %define [LENTER::11] %$186 0 9 ;;; %define lsizeparameters 8 9 ;;; %define __lframe__autoret near 10 $
Not sure whether this is just one and the same error, but I do get a segmentation fault even with only a single instruction and -felf -g. However, this only happens if there is a trailing empty line. $ (echo; echo "pop ebp"; echo) > test1.asm $ nasm -felf -g test1.asm -o test1.o Segmentation fault $ (echo; echo "pop ebp") > test2.asm $ nasm -felf -g test2.asm -o test2.o $
The test $ nasm -felf -g test.asm -o test.o -I ../lmacros/ looks to be working with the latest commit (e91f5cc1322e) without segfault.
I forked my local NASM repo and checked out nasm-2.14.03rc2-445-ge91f5cc1 then tested that. Result is the same as with ca2d991ec, crashes with -felf -g: $ cat test.asm %include "lmacros2.mac" bits 32 lframe near lpar dword, EKey lpar dword, length lenter lleave $ tstnasm --version NASM version 2.15rc0 compiled on Apr 8 2020 $ hg -R ../lmacros/ id aa2ecb95d799 tip $ tstnasm -felf -g test.asm -o test.o -I ../lmacros/ Segmentation fault $ tstnasm -felf test.asm -o test.o -I ../lmacros/ $ tstnasm -fbin -g test.asm -o test.o -I ../lmacros/ $ tstnasm -fbin test.asm -o test.o -I ../lmacros/ $
This line is causing the segfault: https://repo.or.cz/nasm.git/blob/e91f5cc1322eed4da0de81656276e021bf352c3d:/output/outelf.c#l2964 (Recompiled after ./configure --enable-gdb. Tests segfault the same as without that switch.) $ gdb --args tstnasm -felf -g test1.asm -o test1.o GNU gdb (Debian 9.1-2) 9.1 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from tstnasm... (gdb) run Starting program: /home/[...]/tstnasm -felf -g test1.asm -o test1.o Program received signal SIGSEGV, Segmentation fault. dwarf_output (type=64, param=0x5555556ff6c0 <sinfo>) at output/outelf.c:2965 2965 if (!(sects[s->section]->flags & SHF_EXECINSTR)) (gdb) print s $1 = (struct symlininfo *) 0x5555556ff6c0 <sinfo> (gdb) print sects $2 = (struct elf_section **) 0x555555757bc0 (gdb) print s->section $3 = 1 (gdb) print sects[s->section] $4 = (struct elf_section *) 0x0 (gdb) print *sects $5 = (struct elf_section *) 0x555555747aa0 (gdb) print **sects $6 = {data = 0x555555747b20, len = 0, size = 0, nrelocs = 0, index = 16, shndx = 1, type = 1, align = 16, flags = 6, pass_last_seen = 0, entsize = 0, name = 0x555555757ba0 ".text", rel = 0x0, head = 0x0, tail = 0x555555747b00, gsyms = 0x0} (gdb) print *sects[s->section] Cannot access memory at address 0x0 (gdb) print sects[s->section] $7 = (struct elf_section *) 0x0 (gdb) quit A debugging session is active. Inferior 1 [process 1705047] will be killed. Quit anyway? (y or n) y This patch fixes the issue for me: $ git diff diff --git a/output/outelf.c b/output/outelf.c index 4976b680..7dc1a52c 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -2961,6 +2961,9 @@ static void dwarf_output(int type, void *param) s = (struct symlininfo *)param; + if (!sects[s->section]) + return; + /* line number info is only gathered for executable sections */ if (!(sects[s->section]->flags & SHF_EXECINSTR)) return;
The example in BR3392661 touches the same issue here. So, while the attached example is reproducible on my side, strangely enough, I think the fix justifiable.
Looking further into this, I think it should fix the index number, using 's->section - 1' instead of 's->section'. Yes, as someone pointed out in the other bug report, the debug out was not correctly populated with this issue.
*** Bug 3392661 has been marked as a duplicate of this bug. ***
Here is an additional trivial testcase with a few more test results. * "nasm" is nasm-2.14.03rc2-448-gca2d991e from https://github.com/ecm-pushbx/nasm/commit/ca2d991ec9240cb35bad9cd467aea1eab197784d * "oldnasm" is 2.12.02 * "tstnasm" is based on nasm-2.14.03rc2-445-ge91f5cc1 from https://repo.or.cz/nasm.git/commit/e91f5cc1322eed4da0de81656276e021bf352c3d with the additional patch I proposed in comment #5 which is this: $ git diff diff --git a/output/outelf.c b/output/outelf.c index 4976b680..7dc1a52c 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -2961,6 +2961,9 @@ static void dwarf_output(int type, void *param) s = (struct symlininfo *)param; + if (!sects[s->section]) + return; + /* line number info is only gathered for executable sections */ if (!(sects[s->section]->flags & SHF_EXECINSTR)) return; $ * "patnasm" is based on the same revision as tstnasm but has instead the following patch, based on the comment #7: $ git diff diff --git a/output/outelf.c b/output/outelf.c index 4976b680..6175ca48 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -2962,12 +2962,12 @@ static void dwarf_output(int type, void *param) s = (struct symlininfo *)param; /* line number info is only gathered for executable sections */ - if (!(sects[s->section]->flags & SHF_EXECINSTR)) + if (!(sects[s->section - 1]->flags & SHF_EXECINSTR)) return; /* Check if section index has changed */ - if (!(dwarf_csect && (dwarf_csect->section) == (s->section))) - dwarf_findsect(s->section); + if (!(dwarf_csect && (dwarf_csect->section) == (s->section - 1))) + dwarf_findsect(s->section - 1); /* do nothing unless line or file has changed */ if (!debug_immcall) $ Here is the test case and the results of assembling it with -felf -g, then dumping the disassembly + source with objdump -S: $ cat test.asm section .text global foo foo: mov eax, 1234 retn $ nasm -v NASM version 2.15rc0 compiled on Nov 22 2019 $ nasm -felf -g test.asm -o test.o Segmentation fault $ nasm -felf test.asm -o test.o $ objdump -S test.o test.o: file format elf32-i386 Disassembly of section .text: 00000000 <foo>: 0: b8 d2 04 00 00 mov $0x4d2,%eax 5: c3 ret $ oldnasm -v NASM version 2.12.02 compiled on Aug 10 2019 $ oldnasm -felf -g test.asm -o test.old $ objdump -S test.old test.old: file format elf32-i386 Disassembly of section .text: 00000000 <foo>: section .text global foo foo: mov eax, 1234 0: b8 d2 04 00 00 mov $0x4d2,%eax retn 5: c3 ret $ tstnasm -v NASM version 2.15rc0 compiled on Apr 8 2020 $ tstnasm -felf -g test.asm -o test.tst $ objdump -S test.tst test.tst: file format elf32-i386 Disassembly of section .text: 00000000 <foo>: 0: b8 d2 04 00 00 mov $0x4d2,%eax 5: c3 ret $ patnasm -v NASM version 2.15rc0 compiled on Apr 22 2020 $ patnasm -felf -g test.asm -o test.pat $ objdump -S test.pat test.pat: file format elf32-i386 Disassembly of section .text: 00000000 <foo>: section .text global foo foo: mov eax, 1234 0: b8 d2 04 00 00 mov $0x4d2,%eax retn 5: c3 ret $ My earlier patch (tstnasm) does not have any source line debugging information for the .text section of this example case. The newer patch (patnasm) seems to restore that info to be as it should. Note that I only patched the most obvious references in the dwarf_output function; I expect that the change should be done in other places too. Or whatever changed the section numbering to be 1-based should be reverted.
I ended up with this patch in the way which used to be in some old codes: https://repo.or.cz/nasm.git/commitdiff/74b2731f2cef0f1ec8c0c6e6e3dee9492b851e8c
I just tested https://repo.or.cz/nasm.git/commitdiff/74b2731f2cef0f1ec8c0c6e6e3dee9492b851e8c and it seems to succeed, no crash and with debugging information present: $ patnasm -v NASM version 2.15rc0 compiled on Apr 22 2020 $ patnasm -felf -g test.asm -o test.pat $ objdump -S test.pat test.pat: file format elf32-i386 Disassembly of section .text: 00000000 <foo>: section .text global foo foo: mov eax, 1234 0: b8 d2 04 00 00 mov $0x4d2,%eax retn 5: c3 ret $
Thank you!
The below commit should have resolved the issue: commit 74b2731f2cef0f1ec8c0c6e6e3dee9492b851e8c author Chang S. Bae <chang.seok.bae@intel.com> Tue, 21 Apr 2020 09:23:39 +0000 (21 09:23 +0000) committer Chang S. Bae <chang.seok.bae@intel.com> Wed, 22 Apr 2020 00:05:56 +0000 (22 00:05 +0000) outelf: Fix the section index for the debug output The section information delivered to the debug output has an index of the section table. The index should be different from the total number of sections at the moment, the returned value from add_sectname(). So, fix the value. Fixes: b2004511ddde ("ELF: handle more than 32,633 sections")